package com.eight.cloud.springmvc.interceptor;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.eight.cloud.core.global.model.LoginUser;
import com.eight.cloud.redisson.utils.TokenManager;
import org.springframework.beans.BeanUtils;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * 解析用户信息
 *
 * @ClassName: TokenArgumentResolver
 * @Author: TXC
 * @Date: 2024-10-26 14:57
 **/
public class TokenArgumentResolver implements HandlerMethodArgumentResolver {
    private final TokenManager tokenManager;
    ;

    public TokenArgumentResolver(TokenManager tokenManager) {
        this.tokenManager = tokenManager;
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        Class<?> parameterType = parameter.getParameterType();
        // 如果方法参数的类型是 UserInfo 类型或者其子类，则返回 true。
        // 如果方法参数的类型是 Map 类型或者其子类，则返回 true。
        return (LoginUser.class.isAssignableFrom(parameterType)
                || Map.class.isAssignableFrom(parameterType));
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        // 获取request
        HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
        // 从请求头中获取 token
        String token = tokenManager.getAccessToken(request);
        if (StrUtil.isNotBlank(token)) {
            LoginUser user = tokenManager.getLoginUser(token);
            if (ObjectUtil.isNotNull(user)) {
                // 判断参数类型进行返回
                Class<?> parameterType = parameter.getParameterType();
                if (Map.class.isAssignableFrom(parameterType)) {
                    Map<String, Object> map = new HashMap<>();
                    BeanUtils.copyProperties(user, map);
                    return map;
                } else {
                    return user;
                }
            }
        }
        return null;
    }

}
